package com.xiaoyu.lanling.feature.moment

import android.os.Bundle
import android.text.TextUtils
import android.view.View
import cn.dreamtobe.kpswitch.util.KeyboardUtil
import com.opensource.svgaplayer.SVGADrawable
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.app.GlobalUI
import com.xiaoyu.base.data.UserData
import com.xiaoyu.base.event.AppEventBus
import com.xiaoyu.base.event.SimpleEventHandler
import com.xiaoyu.base.utils.RxUtils
import com.xiaoyu.base.utils.extensions.getViewTag
import com.xiaoyu.base.utils.extensions.setOnClickDebounceListener
import com.xiaoyu.base.utils.extensions.setViewTag
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.activity.base.AppCompatToolbarActivity
import com.xiaoyu.lanling.common.Constant
import com.xiaoyu.lanling.data.SvgaData
import com.xiaoyu.lanling.event.coin.CoinAccostEvent
import com.xiaoyu.lanling.event.moment.DeleteMomentEvent
import com.xiaoyu.lanling.event.moment.detail.*
import com.xiaoyu.lanling.feature.coin.data.CoinData
import com.xiaoyu.lanling.feature.moment.data.MomentData
import com.xiaoyu.lanling.feature.moment.dialog.MomentDeleteDialog
import com.xiaoyu.lanling.feature.moment.dialog.MomentReportDialog
import com.xiaoyu.lanling.feature.moment.fragment.detail.CommentListFragment
import com.xiaoyu.lanling.feature.moment.fragment.detail.LikeListFragment
import com.xiaoyu.lanling.feature.moment.model.MomentItem
import com.xiaoyu.lanling.feature.moment.model.detail.CommentItem
import com.xiaoyu.lanling.media.image.ImageViewUtil
import com.xiaoyu.lanling.router.Router
import com.xiaoyu.lanling.util.TextViewUtil
import com.xiaoyu.lanling.view.FragmentAdapter
import com.xiaoyu.lanling.view.OnShowFragment
import com.xiaoyu.lanling.view.listener.BaseTextWatcher
import com.xiaoyu.lanling.widget.svga.SvgaBaseCallback
import com.xiaoyu.lanling.widget.tablayout.ScaleTabLayoutUtils
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.activity_moment_detail.*
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class MomentDetailActivity : AppCompatToolbarActivity() {

    private val requestTag = Any()

    private var mSvgaDisposable: Disposable? = null

    private inner class EditTextWatcher : BaseTextWatcher() {
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            this@MomentDetailActivity.send_button.visibility = if (TextUtils.isEmpty(s)) View.GONE else View.VISIBLE
        }
    }

    override fun onCreateSafelyAfterAppFinishInit(savedInstanceState: Bundle?) {
        setLightStatusBar()
        setContentView(R.layout.activity_moment_detail)
        initView()
        initBind()
        initEvent()
        initData()
    }

    private fun initData() {
        val fid = intent.getStringExtra(Constant.IntentKey.KEY_FEED_ID) ?: return
        MomentData.getMomentDetail(requestTag, fid)
    }

    private fun initBind() {
        avatar.setOnClickListener { v ->
            val moment = v.getViewTag<MomentItem>() ?: return@setOnClickListener
            val user = moment.user ?: return@setOnClickListener
            if (UserData.getInstance().isSelf(user.uid))
                return@setOnClickListener

            Router.instance.gotoUserActivity(this, user)
        }
        action.setOnClickListener { v ->
            val moment = v.getViewTag<MomentItem?>() ?: return@setOnClickListener
            val user = moment.user ?: return@setOnClickListener
            if (UserData.getInstance().isSelf(user.uid)) {
                MomentDeleteDialog.newInstance(user.uid, moment.feed.id).show(supportFragmentManager, MomentDeleteDialog.TAG)
            } else {
                MomentReportDialog.newInstance(moment.feed.id, "", ArrayList(moment.feed.images.map { it.imageUrl })).show(supportFragmentManager, MomentReportDialog.TAG)
            }
        }
        accost_svga?.callback = object : SvgaBaseCallback() {
            override fun onFinished() {
                accost_svga?.visibility = View.GONE
            }
        }
        accost.setOnClickListener { v ->
            val moment = v.getViewTag<MomentItem?>() ?: return@setOnClickListener
            val user = moment.user ?: return@setOnClickListener
            CoinData.accost(requestTag, user.uid)
        }
        like.setOnCheckedChangeListener { button, isChecked ->
            val moment = button.getViewTag<MomentItem?>() ?: return@setOnCheckedChangeListener
            MomentData.like(requestTag, moment, isChecked)
        }
        edit_text.addTextChangedListener(EditTextWatcher())
        comment.setOnClickListener {
            markAsComment()
            KeyboardUtil.showKeyboard(edit_text)
        }
        send_button.setOnClickDebounceListener {
            val moment = it.getViewTag<MomentItem>() ?: return@setOnClickDebounceListener
            val text = edit_text.text.toString()
            val fid = moment.feed.id
            val comment = edit_text.getViewTag<CommentItem>()
            // NOTE null if not reply to certain comment
            val uid = comment?.user?.uid ?: ""
            val cid = comment?.comment?.id ?: ""
            if (TextUtils.isEmpty(text)) {
                return@setOnClickDebounceListener
            }
            send_button.isEnabled = false
            MomentData.comment(requestTag, fid, uid, cid, edit_text.text.toString())
        }
    }

    private fun initEvent() {
        AppEventBus.bindContainerAndHandler(this, object : SimpleEventHandler() {

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: MomentDetailEvent) {
                if (event.isFailed) {
                    GlobalUI.getInstance().showToastForLong(AppContext.getString(R.string.moment_deleted))
                    finish()
                } else {
                    showMomentData(event)
                }
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: CoinAccostEvent) {
                if (event.isNotFromThisRequestTag(requestTag))
                    return
                showAccostSvga()
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: TryReplyCommentEvent) {
                markAsReply(event.comment)
                KeyboardUtil.showKeyboard(edit_text)
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: CommentMomentEvent) {
                initData()
                resetEditor()
                KeyboardUtil.hideKeyboard(edit_text)
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: DeleteCommentEvent) {
                initData()
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: LikeMomentEvent) {
                refreshLike()
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: DeleteMomentEvent) {
                if (event.fid == intent.getStringExtra(Constant.IntentKey.KEY_FEED_ID)) {
                    finish()
                }
            }
        })
    }

    private fun refreshLike() {
        val moment = like.getViewTag<MomentItem>() ?: return
        moment.feed.likeCount += if (like.isChecked) 1 else -1
        like.text = if (moment.feed.likeCount == 0) AppContext.getString(R.string.moment_like) else moment.feed.likeCount.toString()
    }

    private fun markAsReply(comment: CommentItem) {
        edit_text.setViewTag(comment)
        edit_text.hint = AppContext.getString(R.string.moment_reply_hint_prefix, comment.user.name)
    }

    private fun markAsComment() {
        edit_text.setViewTag(null)
        resetEditor()
    }

    private fun resetEditor() {
        send_button.isEnabled = true
        edit_text.setText("")
        edit_text.hint = AppContext.getString(R.string.moment_comment_hint)
    }

    private fun showMomentData(event: MomentDetailEvent) {
        val itemData = event.moment
        ImageViewUtil.loadImage(avatar, itemData.avatarLoadParam)
        name.text = itemData.user.name
        name.setTextColor(AppContext.getColor(if (itemData.vipIcon.isNotEmpty()) R.color.vip_name else R.color.colorOnSurface))
        accost.visibility = if (itemData.feed.isOwner) View.GONE else View.VISIBLE
        accost.isSelected = itemData.accosted
        ImageViewUtil.loadImage(vip, itemData.vipLoadParam)
        verified.visibility = if (itemData.verified) View.VISIBLE else View.GONE
        TextViewUtil.displayOrGone(feed_content, itemData.feed.text)
        moment_images.showData(itemData)
        age.text = itemData.age
        age.setCompoundDrawablesRelativeWithIntrinsicBounds(if (itemData.user.isMale) R.drawable.icon_friend_list_male else R.drawable.icon_friend_list_female, 0, 0, 0)
        age.setBackgroundResource(if (itemData.user.isMale) R.drawable.shape_friend_sex_male else R.drawable.shape_friend_sex_female)
        like.isChecked = itemData.feed.liked
        like.text = if (itemData.feed.likeCount == 0) AppContext.getString(R.string.moment_like) else itemData.feed.likeCount.toString()
        comment.text = if (itemData.feed.commentCount == 0) AppContext.getString(R.string.moment_comment) else itemData.feed.commentCount.toString()
        action.setViewTag(itemData)
        avatar.setViewTag(itemData)
        accost.setViewTag(itemData)
        like.setViewTag(itemData)
        send_button.setViewTag(itemData)
    }

    private fun initView() {
        initToolbar()
        title = AppContext.getString(R.string.moment_detail)

        val feedId = intent.getStringExtra(Constant.IntentKey.KEY_FEED_ID)

        val fragmentList = mutableListOf<OnShowFragment>()
        val commentFragment = CommentListFragment.newInstance(feedId)
        val likeFragment = LikeListFragment.newInstance(feedId)

        fragmentList.add(commentFragment)
        fragmentList.add(likeFragment)

        val titles = listOf<String>(AppContext.getString(R.string.moment_comment), AppContext.getString(R.string.moment_like))
        ScaleTabLayoutUtils.createNormalNoScaleTabLayout(magic_indicator, view_pager, titles)
        val fragmentAdapter = FragmentAdapter(supportFragmentManager, fragmentList, titles)
        view_pager.offscreenPageLimit = fragmentList.size
        view_pager.currentItem = 0
        view_pager.adapter = fragmentAdapter
    }

    private fun showAccostSvga() {
        accost.isSelected = true
        mSvgaDisposable?.dispose()
        mSvgaDisposable = SvgaData.createTaskFromAsset("accost.svga")
                .compose(RxUtils.ioToMainSingleScheduler())
                .subscribe({ entity ->
                    val drawable = SVGADrawable(entity)
                    accost_svga?.visibility = View.VISIBLE
                    accost_svga?.setImageDrawable(drawable)
                    accost_svga?.loops = 1
                    accost_svga?.startAnimation()
                    mSvgaDisposable?.dispose()
                }, { t -> t.printStackTrace() })
    }

    override fun onDestroy() {
        super.onDestroy()
        RxUtils.disposable(mSvgaDisposable)
    }
}